package csc.fresher.view;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import csc.fresher.constant.ProjectBankingConstant;
import csc.fresher.dao.impl.CustomerDaoImpl;
import csc.fresher.dao.impl.SavingAccountDaoImpl;
import csc.fresher.entity.AccountHasInterestRate;
import csc.fresher.entity.AccountTransactionState;
import csc.fresher.entity.Currency;
import csc.fresher.entity.Customer;
import csc.fresher.entity.CustomerAccount;
import csc.fresher.entity.InterestRate;
import csc.fresher.entity.PeriodType;
import csc.fresher.entity.SavingAccount;
import csc.fresher.entity.SavingTransactionType;
import csc.fresher.service.InterestRateService;
import csc.fresher.service.SavingAccountService;
import csc.fresher.service.SavingTransactionService;
import csc.fresher.service.impl.SavingInterestRateServiceImpl;

@Component
@Scope("session")
public class SavingCreateTransManagedBean {

	@Autowired
	SavingAccManagedBean accManagedBean;
	@Autowired
	SavingTransactionService savingTransactionServices;
	@Autowired
	SavingInterestRateServiceImpl savingInterestRateServiceImpl;
	@Autowired
	CustomerDaoImpl customerDaoImpl;
	@Autowired
	SavingAccountService savingAccountService;
	@Autowired
	InterestRateService interestRateService;
	
	private String message = "";
	private CustomerAccount customerAccount;
	private Customer customer;
	private double funds;
	private SavingTransactionType savingTransactionType;
	private double currentBalance;
	private double afterBalance;
	private double newInterestRate;
	private int periodTypeID;
	private String currency;
	private Timestamp expiredDate;
	private InterestRate interestRate;
	
	private double beforeBalance;
	
	@PostConstruct
	public void init() {
		savingTransactionType = SavingTransactionType.SAVING;
		periodTypeID = getPeriodTypes().get(0).getPeriodTypeID();
		funds = 0;
		
		if (accManagedBean != null) {
			customerAccount = accManagedBean.getSelectedAccount();
			setCustomer(accManagedBean.getCustomer());
			if(customerAccount == null || !customerAccount.getAccountTransactionState().getState().equals(AccountTransactionState.ACTIVE.getState())){
				/*customerAccount = savingAccountDaoImpl.getCustomerAccountByID(323456789030L);
				setCustomer(customerDaoImpl.getCustomerByID(customerAccount.getCustomerID()));*/
				redirect("savingAccView.jsf");
			}
		}
	}

	public void clear(){
		savingTransactionType = SavingTransactionType.SAVING;
		periodTypeID = getPeriodTypes().get(0).getPeriodTypeID();
		funds = 0;
	}
	
	public double getFunds() {
		if(savingTransactionType != null && !savingTransactionType.getType().equals("Saving")){
			funds = interestRateService.getInterestAmount(customerAccount, savingTransactionType);
		}
		return funds;
	}

	public void setFunds(double funds) {
		this.funds = funds;
	}
	
	
	public CustomerAccount getCustomerAccount() {
		return customerAccount;
	}

	public void setCustomerAccount(CustomerAccount customerAccount) {
		this.customerAccount = customerAccount;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}


	public List<Currency> getCurrencies() {
		return savingInterestRateServiceImpl.getAllCurrency();
	}
	
	public List<PeriodType> getPeriodTypes(){
		List<PeriodType> liPeriodTypes =  savingInterestRateServiceImpl.getAllPeriodTypes();
		for (PeriodType periodType : liPeriodTypes) {
			if(periodType.getPeriodTypeID() == ProjectBankingConstant.NONE_DURATION){
				liPeriodTypes.remove(periodType);
				break;
			}
		}
		return liPeriodTypes;
	}
	
	public SavingTransactionType[] getTransactionTypes() {
		SavingTransactionType[] savingTransactionTypes = SavingTransactionType.values();
		
		if(customerAccount.getAccountBalance() == 0){
			savingTransactionTypes = new SavingTransactionType[]{SavingTransactionType.SAVING};
		}
		
		
		return savingTransactionTypes;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public double getAfterBalance() {
		this.afterBalance = savingInterestRateServiceImpl.calculateAfterBalance(customerAccount, funds, newInterestRate, periodTypeID, savingTransactionType);
		return this.afterBalance;
	}

	public void setAfterBalance(double afterBalance) {
		this.afterBalance = afterBalance;
	}

	public double getCurrentBalance() {
		this.currentBalance = customerAccount.getAccountBalance(); //savingAccountService.getCurrentAccountBalance(customerAccount);
		return currentBalance;
	}

	public void setCurrentBalance(double currentBalance) {
		this.currentBalance = currentBalance;
	}

	public SavingTransactionType getSavingTransactionType() {
		return savingTransactionType;
	}

	public void setSavingTransactionType(SavingTransactionType savingTransactionType) {
		this.savingTransactionType = savingTransactionType;
	}
	
	public double getNewInterestRate() {
		SavingAccount savingAccount = (SavingAccount) customerAccount;
		
		interestRate = savingInterestRateServiceImpl.getInterestRate(savingAccount.getCurrencyID(), periodTypeID);
		if(interestRate != null){
			newInterestRate = interestRate.getRate();
		}else{
			newInterestRate = 0;
		}
		
		return newInterestRate;
	}
	public void setNewInterestRate(double newInterestRate) {
		this.newInterestRate = newInterestRate;
	}
	public int getPeriodTypeID() {
		return periodTypeID;
	}
	public void setPeriodTypeID(int periodTypeID) {
		this.periodTypeID = periodTypeID;
	}
	
	


	public void createTransaction() {
		long accountNumber = customerAccount.getAccountNumber();
		
		if(savingTransactionServices.checkActiveCustomerAccountTransactionState(accountNumber)){
			message = "Account Deactive is not create transaction!";
		}
		
		
		
		long id = savingTransactionServices.createTransaction(funds, accountNumber, currentBalance, (int) accManagedBean.getSystemUser().getSystemUserID(), savingTransactionType, interestRate.getInterestRateID(), new Timestamp(System.currentTimeMillis()), expiredDate);
		//long id = saving
		System.out.println(id);
		if(id > 0){
			clear();
			redirect("savingAccView.jsf");
		} else if(id == ProjectBankingConstant.ACCOUNT_NOT_ACTIVE){
			message = "Account Deactive is not create transaction!";
		}else if(id == -2) {
			message = "Funds not null!";
		}else{
			message = "Error has occurred.";
		}
	}

	public void back(){
		clear();
		redirect("savingAccView.jsf");
	}


	public Timestamp getExpiredDate() {
		expiredDate = savingInterestRateServiceImpl.getExpiryDate(periodTypeID);
		System.out.println(expiredDate);
		return expiredDate;
	}

	public void setExpiredDate(Timestamp expiredDate) {
		this.expiredDate = expiredDate;
	}



	public String getCurrency() {
		SavingAccount savingAccount = (SavingAccount) customerAccount;
		List<Currency> currencies = getCurrencies();
		for (Currency currency : currencies) {
			if(currency.getCurrencyID() == savingAccount.getCurrencyID()){
				this.currency = currency.getCurrency();
			}
		}
		
		return this.currency;
	}



	public void setCurrency(String currency) {
		this.currency = currency;
	}
	
	private void redirect(String url) {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();
		try {
			externalContext.redirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
